package com.tomek.ktoryoperator.utils;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.PhoneLookup;

import com.tomek.ktoryoperator.R;
import com.tomek.ktoryoperator.db.NetworkProviderContentProvider;
import com.tomek.ktoryoperator.model.DBEntry;
import com.tomek.ktoryoperator.model.SingleEntry;

public class ContentProvidersUtils {
	public static void insertEntry(ContentResolver cr, String number, String provider, String value) {
		ContentValues cv = new ContentValues();

		cv.put(NetworkProviderContentProvider.KEY_NUMBER, number);
		cv.put(NetworkProviderContentProvider.KEY_DATE, System.currentTimeMillis());
		cv.put(NetworkProviderContentProvider.KEY_PROVIDER, provider);
		cv.put(NetworkProviderContentProvider.KEY_VALUE, value);

		cr.insert(NetworkProviderContentProvider.CONTENT_ALL_ENTRIES_URI, cv);
	}

	public static void updateEntry(ContentResolver cr, int id, String provider, String value) {
		ContentValues cv = new ContentValues();

		cv.put(NetworkProviderContentProvider.KEY_DATE, System.currentTimeMillis());
		cv.put(NetworkProviderContentProvider.KEY_PROVIDER, provider);
		cv.put(NetworkProviderContentProvider.KEY_VALUE, value);

		Uri uri = Uri.withAppendedPath(NetworkProviderContentProvider.CONTENT_ENTRY_BY_ID_URI, String.valueOf(id));
		cr.update(uri, cv, null, null);
	}

	public static DBEntry load(ContentResolver cr, String number) {
		Uri uri = Uri.withAppendedPath(NetworkProviderContentProvider.CONTENT_ENTRY_BY_NUMBER_URI, number);

		Cursor c = cr.query(uri, null, null, null, null);

		DBEntry entry = null;

		if (c.moveToFirst()) {
			entry = createEntryFromCursor(c);
		}

		c.close();

		return entry;
	}

	public static ArrayList<String> getNumbersToRead(ContentResolver contentResolver, int count) {
		HashSet<String> numbersAlreadyRead = new HashSet<String>();
		ArrayList<String> numbersToRead = new ArrayList<String>();

		Cursor c = contentResolver.query(NetworkProviderContentProvider.CONTENT_ALL_ENTRIES_URI, null, null, null,
				NetworkProviderContentProvider.KEY_DATE);
		while (c.moveToNext()) {
			String number = c.getString(NetworkProviderContentProvider.COLUMN_NUMBER);
			numbersAlreadyRead.add(number);
		}
		c.close();

		Cursor c2 = contentResolver.query(Phone.CONTENT_URI, new String[] { Phone.DISPLAY_NAME, Phone.NUMBER }, null,
				null, Phone.DISPLAY_NAME);

		if (c2.moveToFirst()) {
			int idxNumber = c2.getColumnIndex(Phone.NUMBER);

			do {
				String number = c2.getString(idxNumber);

				if (number == null || numbersAlreadyRead.contains(number)) {
					continue;
				}

				numbersToRead.add(number);

				if (numbersToRead.size() == count) {
					break;
				}

			} while (c2.moveToNext());
		}
		c2.close();

		return numbersToRead;
	}

	public static void deleteData(ContentResolver contentResolver) {
		contentResolver.delete(NetworkProviderContentProvider.CONTENT_ALL_ENTRIES_URI, null, null);
	}

	public static ArrayList<DBEntry> getNewEntries(ContentResolver contentResolver, long updateTime) {
		Cursor c = contentResolver.query(NetworkProviderContentProvider.CONTENT_ALL_ENTRIES_URI, null,
				NetworkProviderContentProvider.KEY_DATE + "> ?", new String[] { String.valueOf(updateTime) }, null);

		ArrayList<DBEntry> entries = new ArrayList<DBEntry>();

		while (c.moveToNext()) {
			entries.add(createEntryFromCursor(c));
		}

		c.close();

		return entries;

	}

	private static DBEntry createEntryFromCursor(Cursor c) {
		String provider = c.getString(NetworkProviderContentProvider.COLUMN_PROVIDER);
		String value = c.getString(NetworkProviderContentProvider.COLUMN_VALUE);
		long date = c.getLong(NetworkProviderContentProvider.COLUMN_DATE);
		int id = c.getInt(NetworkProviderContentProvider.COLUMN_ID);
		String number = c.getString(NetworkProviderContentProvider.COLUMN_NUMBER);

		return new DBEntry(provider, value, date, number, id);
	}

	public static HashMap<String, SingleEntry> readContacts(Context context, ContentResolver contentResolver) {
		HashMap<String, SingleEntry> map = new HashMap<String, SingleEntry>();

		Cursor cursor = contentResolver.query(Phone.CONTENT_URI, new String[] { Phone.NUMBER, Phone.DISPLAY_NAME,
				Phone.CONTACT_ID, Phone.RAW_CONTACT_ID, Phone.TYPE, Phone.DATA4 }, null, null, null);

		HashMap<Integer, Bitmap> photosMap = new HashMap<Integer, Bitmap>();

		while (cursor.moveToNext()) {
			Integer contactId = cursor.getInt(cursor.getColumnIndex(Phone.CONTACT_ID));
			// Integer rawContactId = cursor.getInt(cursor.getColumnIndex(Phone.RAW_CONTACT_ID));
			String number = cursor.getString(cursor.getColumnIndex(Phone.NUMBER));
			String displayName = cursor.getString(cursor.getColumnIndex(Phone.DISPLAY_NAME));
			//String numberType = cursor.getString(cursor.getColumnIndex(Phone.TYPE));
			String clearNumber = cursor.getString(cursor.getColumnIndex(Phone.DATA4));

			StringBuilder sb = new StringBuilder(clearNumber);
			number = sb.reverse().toString();
			number = TelephonyUtils.cleanNumber(number);

			if (!photosMap.containsKey(contactId)) {
				Uri uri = ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, contactId);

				Bitmap bitmap = null;
				InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(contentResolver, uri);

				if (input == null) {
					bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_contact_picture_m);
				} else {
					bitmap = BitmapFactory.decodeStream(input);
				}

				photosMap.put(contactId, bitmap);
			}

			SingleEntry se = new SingleEntry(displayName, number);
			se.avatar = photosMap.get(contactId);

			map.put(number, se);
		}
		cursor.close();

		return map;
	}

	public static String getContactNameForNumber(ContentResolver cr, String number) {
		String[] projection = new String[] { Phone.DISPLAY_NAME };

		Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));

		Cursor c = cr.query(uri, projection, null, null, null);
		String name = null;

		if (c.moveToFirst()) {
			name = c.getString(c.getColumnIndex(Phone.DISPLAY_NAME));
		}

		c.close();

		return name;
	}
}